﻿//////////////////////////////////////////////////////////////////////////////////
//
// Project            : SimpleProxySwitch
// Module             : SimpleProxySwitch
// Description        : Dialog to edit proxy setting.
// 
// Repository         : $URL$
// Last changed by    : $LastChangedBy$
// Revision           : $LastChangedRevision$
// Last Changed       : $LastChangedDate$
// Author             : $Author$
//
// Id                 : $Id$
//
// Copyright          : (c) 2010 Torsten Bär
//
// Published under the MIT License. See license.txt or http://www.opensource.org/licenses/mit-license.php.
//
//////////////////////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Windows.Forms;
using log4net;

namespace ProxySwitch
{
   /// <summary>
   /// Dialog to edit proxy setting.
   /// </summary>
   public sealed partial class EditProxyForm : Form
   {
      private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

      /// <summary>
      /// Gets the setting.
      /// </summary>
      public ProxySetting Setting { get; private set; }

      private string ProxyAddress { get; set; }
      private string Bypass { get; set; }
      private string networkMask;

      /// <summary>
      /// Gets or sets the network mask.
      /// </summary>
      private string NetworkMask
      {
         get
         {
            if (networkMask == null)
            {
               Log.Debug("Initializing network mask");

               networkMask = Network.Current;
            }
            return networkMask;
         }
         set
         {
            Log.Debug("Setting network mask");

            networkMask = value;
         }
      }

      /// <summary>
      /// Initializes a new instance of the <see cref="EditProxyForm"/> class.
      /// </summary>
      public EditProxyForm()
      {
         Log.Debug("Initialiting components");

         InitializeComponent();

         Log.Debug("Setting network mask");

         if (NetworkMask != null)
            textBoxNetworkMask.Text = NetworkMask;
      }

      /// <summary>
      /// Initializes a new instance of the <see cref="EditProxyForm"/> class.
      /// </summary>
      /// <param name="proxy">The proxy setting.</param>
      public EditProxyForm(ProxySetting proxy)
         : this()
      {
         Log.Debug("Initializing with proxy setting");

         Setting = proxy;

         if (Setting != null)
         {
            Log.DebugFormat("Initialized with network setting {0} {1} {2}", proxy.Address, proxy.Network, proxy.Bypass);

            textBoxProxyAddress.Text = Setting.Address;
            textBoxBypassPatterns.Text = Setting.Bypass;
            textBoxNetworkMask.Text = Setting.Network;
         }
         else
         {
            Log.Debug("Proxysetting == null");
         }
      }

      /// <summary>
      /// Handles the Click event of the button control.
      /// </summary>
      /// <param name="sender">The source of the event.</param>
      /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
      private void button_Click(object sender, EventArgs e)
      {
         if (Log.IsDebugEnabled)
         {
            Control control = sender as Control;
            Log.DebugFormat("Handling click event of {0}", control != null ? control.Name : "no conrol");
         }

         if (sender == buttonAccept)
         {
            ProxyAddress = textBoxProxyAddress.Text;
            NetworkMask = textBoxNetworkMask.Text;
            Bypass = textBoxBypassPatterns.Text;

            Log.Debug("Initialize setting");

            Setting = new ProxySetting(ProxyAddress, NetworkMask, Bypass);
         }
         else if (sender == buttonGetCurrentProxy)
         {
            ProxySetting proxySetting = Network.SystemProxy;

            Log.Debug("Got current proxy setting");

            textBoxProxyAddress.Text = proxySetting.Address;
            textBoxBypassPatterns.Text = proxySetting.Bypass;
         }

         Log.Debug("Event handled");
      }

      /// <summary>
      /// Handles the Validating event of the textBox control.
      /// </summary>
      /// <param name="sender">The source of the event.</param>
      /// <param name="e">The <see cref="System.ComponentModel.CancelEventArgs"/> instance containing the event data.</param>
      private void textBox_Validating(object sender, CancelEventArgs e)
      {
         Log.Debug("Validating input");

         TextBox textBox = sender as TextBox;

         if (textBox == null)
         {
            Log.Debug("No textbox");
            return;
         }

         Log.DebugFormat("Validating input of", textBox.Name);

         if (!String.IsNullOrEmpty(textBox.Text))
         {
            if (sender == textBoxProxyAddress)
            {
               Log.Debug("Validating proxy address");

               e.Cancel = !Validator.IsValidUri(textBoxProxyAddress.Text);

               ProxyAddress = e.Cancel ? null : textBoxProxyAddress.Text;

               errorProvider.SetError(textBox, e.Cancel ? "Invalid IP addresss" : null);
            }
            else if (sender == textBoxNetworkMask)
            {
               Log.Debug("Validating network mask");

               e.Cancel = !Validator.IsValidNetworkMask(textBoxNetworkMask.Text);

               NetworkMask = e.Cancel ? null : textBoxNetworkMask.Text = Network.GetCidrMask(textBoxNetworkMask.Text);

               errorProvider.SetError(textBox, e.Cancel ? "Invalid network mask" : null);
            }
            else if (sender == textBoxBypassPatterns)
            {
               Log.Debug("Validating bypass pattern");

               IList<string> errors = new List<string>();
               e.Cancel = !Validator.IsValidBypassList(textBoxBypassPatterns.Text, errors);

               Bypass = e.Cancel ? null : textBox.Text;

               errorProvider.SetError(textBox, e.Cancel ? errors.ToString() : null);
            }
            else
            {
               Log.Error("Unknown textbox");
            }
         }

         if (Log.IsDebugEnabled)
            Log.DebugFormat("Input validated; Error {0}", errorProvider.GetError(textBox));
      }
   }
}
